from pycparser import c_parser
import networkx as nx
import json

from utils.parseData import response_json,add_line_numbers
from utils.sendGpt import send_prompt_openai_gpt


# 读取静态 Prompt 文件
def load_cfgprompt():
    with open("static/prompts_cfg.json", "r", encoding="utf-8") as file:
        return json.load(file)

def load_dupathprompt():
    with open("static/prompts_dupath.json", "r", encoding="utf-8") as file:
        return json.load(file)

def load_astcfgprompt():
    with open("static/prompts_astcfg.json", "r", encoding="utf-8") as file:
        return json.load(file)


def generate_cfg_with_gpt(code,language,model):

    # re = {
    #   "nodes": [
    #     { "id": 1, "label": "Start" },
    #     { "id": 2, "label": "printf(\"Hello, World!\\n\")" },
    #     { "id": 3, "label": "return 0;" },
    #     { "id": 4, "label": "En
    #   ],
    #   "edges": [
    #     { "source": 1, "target": 2 },
    #     { "source": 2, "target": 3 },
    #     { "source": 3, "target": 4 }
    #   ]
    # }
    # re = json.dumps(re)
    # return response_json(200, "Success", re)
    code = add_line_numbers(code)
    """
    使用 ChatGPT 解析代码并生成控制流图（CFG）。
    """
    prompts = load_cfgprompt()
    prompt_template = prompts[language]  # 获取存储的 Prompt
    prompt = prompt_template.format(code=code)  # 动态插入代码
    try:
        cfg_json = send_prompt_openai_gpt(prompt,model)
        return response_json(200, "Success", cfg_json)
    except Exception as e:
        return response_json(515, "Error", str(e))

def generate_dupath_with_gpt(code,language,model):

    # re = {
    #   "nodes": [
    #     { "id": 1, "label": "Start" },
    #     { "id": 2, "label": "printf(\"Hello, World!\\n\")" },
    #     { "id": 3, "label": "return 0;" },
    #     { "id": 4, "label": "End" }
    #   ],
    #   "edges": [
    #     { "source": 1, "target": 2 },
    #     { "source": 2, "target": 3 },
    #     { "source": 3, "target": 4 }
    #   ]
    # }
    # re = json.dumps(re)
    # return response_json(200, "Success", re)
    code = add_line_numbers(code)



    """
    使用 ChatGPT 解析代码并生成控制流图（CFG）。
    """
    prompts = load_dupathprompt()
    prompt_template = prompts[language]  # 获取存储的 Prompt
    # print(prompt_template)
    # print(code)
    prompt = prompt_template.format(code=code)  # 动态插入代码
    try:
        # print(prompt)
        du_json = send_prompt_openai_gpt(prompt,model)
        # print(du_json)
        return response_json(200, "Success", du_json)
    except Exception as e:
        return response_json(515, "Error", str(e))

def generate_cfg_with_astandgpt(preprocessed_code,language,model):
    parser = c_parser.CParser()
    try:
        ast = parser.parse(preprocessed_code)
    except Exception as e:
        return response_json(515, "Error", str(e))
    print(ast)
    """
        使用 ChatGPT 解析AST并生成控制流图（CFG）。
    """
    prompts = load_astcfgprompt()
    prompt_template = prompts[language]  # 获取存储的 Prompt
    # print(prompt_template)
    # print(code)
    prompt = prompt_template.format(ast=ast)  # 动态插入代码
    try:
        cfg_json = send_prompt_openai_gpt(prompt, model)
        return response_json(200, "Success", cfg_json)
    except Exception as e:
        return response_json(515, "Error", str(e))

def generate_cfg(c_code):
    """
    解析 C 代码并生成控制流图（CFG）。
    """
    parser = c_parser.CParser()
    try:
        ast = parser.parse(c_code)
    except Exception as e:
        return {"error": f"代码解析错误: {str(e)}"}

    G = nx.DiGraph()
    node_counter = [0]  # 用于标记节点 ID

    def traverse(node, parent=None):
        """ 递归遍历 AST，构建 CFG """
        if node is None:
            return

        node_id = node_counter[0]
        node_counter[0] += 1
        G.add_node(node_id, label=str(type(node).__name__))  # 以 AST 节点类型作为标签

        if parent is not None:
            G.add_edge(parent, node_id)

        for child in node.children():
            traverse(child[1], node_id)

    traverse(ast)

    return nx.node_link_data(G)  # 返回 JSON 格式的图数据